import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

// 设计思路：简单的NIO客户端，连接到服务器，发送用户输入的消息，并接收广播消息
public class NIOClient {
    private static final String HOST = "localhost";
    private static final int PORT = 8080;
    private SocketChannel clientChannel;
    private ByteBuffer buffer = ByteBuffer.allocate(1024);

    // 初始化客户端并连接到服务器
    public NIOClient() throws IOException {
        clientChannel = SocketChannel.open();
        clientChannel.configureBlocking(false);
        clientChannel.connect(new InetSocketAddress(HOST, PORT));

        // 完成连接
        while (!clientChannel.finishConnect()) {
            // 等待连接完成
        }
        System.out.println("已连接到服务器 " + HOST + ":" + PORT);
    }

    // 发送消息到服务器
    public void sendMessage(String message) throws IOException {
        // 添加换行符以符合协议
        String formattedMessage = message + "\n";
        ByteBuffer writeBuffer = ByteBuffer.wrap(formattedMessage.getBytes(StandardCharsets.UTF_8));
        clientChannel.write(writeBuffer);
    }

    // 接收服务器广播的消息
    public void receiveMessages() throws IOException {
        buffer.clear();
        int bytesRead = clientChannel.read(buffer);
        if (bytesRead == -1) {
            System.out.println("与服务器断开连接");
            clientChannel.close();
            return;
        }
        if (bytesRead > 0) {
            buffer.flip();
            byte[] bytes = new byte[bytesRead];
            buffer.get(bytes);
            String message = new String(bytes, StandardCharsets.UTF_8);
            System.out.print("收到消息: " + message);
        }
    }

    // 主循环，处理用户输入和消息接收
    public void start() {
        // 使用单独线程处理消息接收
        Thread receiverThread = new Thread(() -> {
            while (true) {
                try {
                    receiveMessages();
                    Thread.sleep(100); // 防止CPU过载
                } catch (IOException | InterruptedException e) {
                    System.err.println("接收消息错误: " + e.getMessage());
                    break;
                }
            }
        });
        receiverThread.start();

        // 主线程处理用户输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入消息（输入'exit'退出）：");
        while (true) {
            String input = scanner.nextLine();
            if ("exit".equalsIgnoreCase(input)) {
                break;
            }
            try {
                sendMessage(input);
            } catch (IOException e) {
                System.err.println("发送消息错误: " + e.getMessage());
                break;
            }
        }
        scanner.close();
        try {
            clientChannel.close();
        } catch (IOException e) {
            System.err.println("关闭客户端错误: " + e.getMessage());
        }
    }

    public static void main(String[] args) {
        try {
            NIOClient client = new NIOClient();
            client.start();
        } catch (IOException e) {
            System.err.println("客户端错误: " + e.getMessage());
        }
    }
}